<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script type="text/javascript" src="../js/vue.js"></script>
  </head>
  <body>
    <!-- 
    vm的生命周期↓
        将要创建 ====> beforeCreate函数
        创建完毕 ====> created函数
        将要挂载 ====> beforeMount函数
        挂载完毕 ====> mounted函数（重要的钩子）
        将要更新 ====> beforeUpdate函数
        更新完毕 ====> updated函数
        将要销毁 ====> beforeDestroy函数（重要的钩子
        销毁完毕 ====> destroyed
    -->
    <div id="root" :x="n">
      <!-- el's outerHTML 也算。也就是包括root这个div也是被当做模板解析-->
      <h1>当前n值是{{n}}</h1>
      <h2>当前n值是{{n}}</h2>
      <h3 v-text="n"></h3>
      <button @click="add()">点我n+1</button>
      <button @click="bye">点我销毁vm</button>
    </div>
    <script type="text/javascript">
      Vue.config.productionTip = false;
      const vm = new Vue({
        /*  template配置项
            如果没有模板，这个配置项会被当成模板拿去解析。直接id="root"的整坨div，包括root
            而且这个template只能用一个根，最好用div包裹起来
        */
        // template:`<div><h2>当前n值是{{n}}</h2></div>`,
        data: {
          n: 1,
        },
        watch: {
          n: {
            handler() {
              console.log("n变了");
            },
          },
        },
        methods: {
          add() {
            console.log("add");
            this.n += 1;
          },
          bye() {
            console.log("bye");
            this.$destroy();
          },
        },
        /*  第一个生命周期函数 beforeCreate
            [无法]通过vm访问到data中的数据（数据代理都没开始）、methods方法
        */
        beforeCreate() {
          console.log("beforeCreate");
          //   console.log(this); // 生命周期的函数this全是vm
          //   debugger; // 打断点
        },
        /*  第二个生命周期函数 created
            [可以]通过vm访问到data中的数据（数据监测和数据代理已经完成）、methods方法*/
        created() {
          console.log("created");
          //   console.log(this); // 生命周期的函数this全是vm
          //   debugger; // 打断点
        },
        /*  第三个生命周期函数 beforeMount
            1.页面呈现的是未经Vue编译的DOM结构
            2.所有对DOM的操作，（最终）都不奏效。因为可以自娱自乐手动改着玩
        */
        beforeMount() {
          console.log("beforeMount");
          //   console.log(this);
          //   改了，如改
          document.querySelector("h2").innerHTML = "哈哈"; // 如改，但继续执行会到这一步：vue将虚拟DOM转为真实DOM插入页面
          //   debugger;
        },
        /*  第四个生命周期函数 mounted
            1.页面中呈现的是经过 Vue 编译的 DOM
            2.对 DOM 的操作均有效（尽可能避免）
                至此初始化过程结束。一般在此进行：开启定时器、发送网络请求、订阅消息、绑定自定义事件等初始化操作
         */
        mounted() {
          console.log("mounted");
          //   console.log(this);
          //   改了，如改
          document.querySelector("h2").innerHTML = "哈哈haha";
          //   debugger;
        },

        /*  第五个生命周期函数 beforeUpdate 当数据更新，beforeUpdate和updated总是触发
            数据是新的，页面是旧的。也就是页面和数据还没同步
        */
        beforeUpdate() {
          console.log("beforeUpdate");
          //   console.log(this);
          //   debugger;
        },
        /*  在 beforeUpdate 和 updated 之间，生成新DOM，新旧DOM比较最终完成页面更新*/
        /*  第六个生命周期函数 updated
            数据是新的，页面也是新的
        */
        updated() {
          console.log("updated");
          //   console.log(this);
          //   debugger;
        },
        /*  第七个生命周期函数 beforeDestroy
            此时：vm中所有的 data、methods、指令等等，都处于可用状态，！！！但不会触发更新
            马上要执行销毁过程，一般在次阶段：关闭定时器、取消订阅消息、解绑 “自定义事件” 等收尾操作
                监听事件等等比如点击事件，是给原生DOM加入的，所以不会消失
        */
        beforeDestroy() {
          console.log("beforeDestroy");
          this.add(); // 能访问数据、但是修改了却不会触发页面更新了
        },
        destroyed() {
          console.log("destroyed");
        },
      });
      vm.$mount("#root");
      console.log(vm.$el instanceof HTMLElement); // vm身上的 $el 就是真实DOM
    </script>
  </body>
</html>
